// 装饰者模式能够在不更改源代码自身的情况下，对其进行职责添加。相比于继承装饰器的做法更轻巧。通俗的讲我们给心爱的手机上贴膜，带手机壳，贴纸，这些就是对手机的装饰。

// 优点：
// 装饰类和被装饰类它们之间可以相互独立发展，不会相互耦合，装饰器模式是继承的一个替代模式，它可以动态的扩展一个实现类的功能。

// 缺点：
// 多层的装饰会增加复杂度

// 允许向一个现有的对象添加新的功能，同时又不改变其结构。这种类型的设计模式属于结构型模式，它是作为现有的类的一个包装
// 可以进行切面编程aop
function test() {
  alert(2);
  return 'test';
}

// 挂载 self => test 执行before回调 执行self after自己执行回调
Function.prototype.before = function (fn) {
  var _self = this;
  return function () {
    // this指向调用的函数
    // console.log(this)
    if (fn.apply(this, arguments) == false) {
      return false;
    }
    // _self.apply(_self, arguments);
    return _self.apply(_self, arguments); // 保留函数的返回值
  };
};

Function.prototype.after = function (fn) {
  var _self = this;
  return function () {
    // _self.apply(_self, arguments);
    var result = _self.apply(_self, arguments); // 拿到before的返回值，最终return出去
    if (result == false) {
      return false;
    }
    fn.apply(this, arguments);
    return result;
  };
};

// test.before(function() {
//     alert(1)
// }).after(function() {
//     alert(3)
// })()

test
  .after(function () {
    alert(3);
  })
  .before(function () {
    alert(1);
    // return false
  })();
